// Perspective
// (c) jimon game studio

#ifndef JEH_CPERSPECTIVE_CONSOLE
#define JEH_CPERSPECTIVE_CONSOLE

#include "IPerspective_Console.h"
#include "ISceneManager.h"
#include "IScriptManager.h"
#include "IFileSystem.h"
#include "IImageLoader.h"
#include "jeInputController.h"
#include "IFpsCounter.h"
#include "ITimer.h"

namespace je
{
	namespace app
	{
		//! Perspective
		class CPerspective_Console:public je::app::IPerspective_Console
		{
		private:
			//! Console Animator
			class jeConsoleAnimator:public scene::IAnimator
			{
			public:
				enum ConsoleState
				{
					CS_NOTHING,
					CS_OPEN,
					CS_OPENED,
					CS_CLOSE,
					CS_CLOSED
				};
			protected:
				ConsoleState State;
				jeVector2df Positions;
			public:
				//! Constructor
				jeConsoleAnimator()
					:IAnimator("ConsoleAnimator"),State(CS_NOTHING)
				{
				}

				//! Destructor
				~jeConsoleAnimator()
				{
				}

				//! Set State
				void SetState(ConsoleState NewState)
				{
					State = NewState;

					if(State == CS_OPEN)
						ParentNode->SetVisible(true);
				}

				//! Get State
				ConsoleState GetState()
				{
					return State;
				}

				//! Set Positions
				void SetPositions(const jeVector2df & NewPositions)
				{
					Positions = NewPositions;
				}

				//! On Update
				void OnUpdate()
				{
					f32 SP = 60.0f * JEDT32;

					switch(State)
					{
					case CS_OPEN:
						{
							ParentNode->SetPosition(jeVector3df(0,-SP,0),true);
							if(ParentNode->GetPosition().Y < Positions.X)
							{
								ParentNode->SetPosition(jeVector3df(0,Positions.X,0));
								State = CS_OPENED;
							}
							break;
						};
					case CS_CLOSE:
						{
							ParentNode->SetPosition(jeVector3df(0,SP,0),true);
							if(ParentNode->GetPosition().Y > Positions.Y)
							{
								ParentNode->SetPosition(jeVector3df(0,Positions.Y,0));
								ParentNode->SetVisible(false);
								State = CS_CLOSED;
							}
							break;
						};
					default:
						{
							break;
						}
					}
					IAnimator::OnUpdate();
				}
			};

			//! Cursor Animator
			class jeCursorAnimator:public scene::IAnimator
			{
			protected:
				f32 LastTime;
				f32 DeltaTime;
			public:
				//! Constructor
				jeCursorAnimator()
					:IAnimator("CursorAnimator"),LastTime(0.0f),DeltaTime(400.0f)
				{
				}

				//! Destructor
				~jeCursorAnimator()
				{
				}

				//! On Update
				void OnUpdate()
				{
					f32 Time = JETIME;
					if(!ParentNode->GetParent()->IsVisible())
						ParentNode->SetVisible(false);
					else
						if((Time - LastTime)>DeltaTime)
						{
							LastTime = Time;
							ParentNode->SetVisible(!ParentNode->IsVisible());
						}

					IAnimator::OnUpdate();
				}
			};


			u1 Run;
			video::jeRenderWindow * CurrentRenderWindow;
			scene::ISceneManager * SceneManager;
			scene::ICameraSceneNode * Camera;

			jeVector2di WorkScreenSize;

			scene::ISceneNode * Console;
			jeConsoleAnimator * ConsoleAnimator;
			scene::ISpriteSceneNode * ConsoleBG;
			scene::ISpriteSceneNode * ConsoleBGAvatar;
			scene::ISceneNode * ConsoleText;
			scene::ISceneNode * ConsoleCursor;
			scene::ITextSceneNode * ConsoleInput;

			scene::ITextSceneNode * FpsText;

			u1 ConsoleOpen;
			s32 ConsoleSelect;

			typedef jeList<scene::ITextSceneNode*> ConsoleTextListType;
			ConsoleTextListType ConsoleTextList;

			input::jeInputController * ConsoleInputKeyConsole;
			input::jeInputController * ConsoleInputKeyEnter;
			input::jeInputController * ConsoleInputKeyUp;
			input::jeInputController * ConsoleInputKeyDown;
			input::jeInputController * ConsoleInputText;

			//! On Resize
			void OnResize();

			//! Create Text
			scene::ITextSceneNode * CreateText(const jeStringd & Text = "",scene::ISceneNode * Parent = NULL);
		public:
			//! Constructor
			CPerspective_Console(video::jeRenderWindow * RenderWindow);

			//! Destructor
			~CPerspective_Console();

			//! Tick
			void Tick();

			//! On Update
			void OnUpdate();

			//! On Render
			void OnRender();

			//! Set Run
			void SetRun(u1 Mode);

			//! Return true if run
			u1 IsRun();

			//! Push Text To Console
			void PushTextToConsole(const jeStringd & Text);

			//! Clear Log
			void ClearLog();
		};
	}
}

#endif
